<!-- 模拟俄罗斯方块 -->
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>模拟俄罗斯方块</title>
    <style>
        canvas {
            background-color: black;
        }
    </style>
</head>

<body>
    <canvas id="canvas"></canvas>
</body>
<script src="../utils.js"></script>
<script>
    // 绘制方形
    class Rect {
        constructor(options) {
            this.x = 0;
            this.y = 0;
            this.w = 100;
            this.h = 50;
            this.fillStyle = 'blue';
            this.strokeStyle = 'black';
            // 小球缩放
            this.scaleX = 1;
            this.scaleY = 1;
            // 定义小球移动速度
            this.vx = 0;
            this.vy = 0;
            // 小球透明度
            this.alpha = 1;
            Object.assign(this, options);
            return this;
        }
        render(ctx) {
            let { x, y, w, h, fillStyle, strokeStyle, scaleX, scaleY, alpha } = this;
            // 保存绘图环境
            ctx.save();
            // 开始绘制
            // ctx.beginPath();
            ctx.beginPath();
            // ctx.translate(x, y);
            ctx.scale(scaleX, scaleY);
            ctx.strokeStyle = strokeStyle;
            ctx.fillStyle = fillStyle;

            ctx.globalAlpha = alpha;
            // console.log('x', y);

            // 绘制矩形
            ctx.rect(x - w / 2, y - h / 2, w, h);

            ctx.fill();
            ctx.stroke();
            ctx.restore();
            ctx.closePath();
            return this;
        }
        // 判断点是否在图形内部
        isInside(x, y) {
            return x <= this.w / 2 && x > this.w / 2 && y <= this.h / 2 && y > this.h / 2;
        }
    }
    let canvas = document.getElementById('canvas');
    let ctx = canvas.getContext('2d');
    let w = canvas.width = 500;
    let h = canvas.height = 500;
    // 用于存储所有长方形
    let rects = [];

    /**
     * 创建一个正方体
     */
    function createRect() {
        // 正方体都从最上面开始往下掉
        let rect = new Rect({
            x: c.rand([0, w]),
            y: 0,
            fillStyle: `rgb(${c.rand([50, 255])},${c.rand([50, 255])},${c.rand([50, 255])})`,
            w: c.rand([10, 100]),
            h: c.rand([10, 100]),
            vy: 1,
        });
        rects.push(rect);
        return rect;
    }

    /**
     * 判断两个正方体是否碰撞
     * @param {Object} rect1 
     * @param {Object} rect2 
     * @return {bool}
     */
    function isBoom(rect1, rect2) {
        console.log('boom');
        return Math.abs(rect1.x - rect2.x) <= rect1.w / 2 + rect2.w / 2 && Math.abs(rect1.y - rect2.y) <= rect1.h / 2 + rect2.h / 2;
    }

    /**
     * 检测边界
     * @param {Object} rect
     * @return {bool}
     */
    function checkBound(rect) {
        return rect.y + rect.h / 2 >= h || rect.x + rect.w / 2 >= w || rect.x + rect.w / 2 <= -w;
    }

    let activeRect = createRect();
    // 重力加速度
    let g = 0.02;
    document.addEventListener('keydown', function (e) {
        switch (e.keyCode) {
            case 37:
                activeRect.x += -5;
                break;
            case 39:
                activeRect.x += 5;
                break;
            case 40:
                g = 0.2;
                break;
        }
    });

    document.addEventListener('keyup', function (e) {
        g = 0.02;
    });
    // 由于长方形碰撞后位置就固定，在rect实例中已经记录了，只对最新的rect进行操作即可
    (function move() {
         window.requestAnimationFrame(move);
        

        ctx.clearRect(0, 0, w, h);
        activeRect.vy += g;
        activeRect.x += activeRect.vx;
        activeRect.y += activeRect.vy;

        if (checkBound(activeRect)) {
            activeRect.y = h - activeRect.h / 2;
            activeRect = createRect();
        }

        // 碰撞检测
        // rects.forEach((rect, index) => {
        //     // if (isBoom(activeRect, rect)) {
        //     //     activeRect.vx = 0;
        //     //     activeRect.vy = 0;
        //     //     // 将方块放入rects保存，然后生成一个新的
        //     //     rects.push(activeRect);
        //     //     console.log('碰撞了');
        //     //     activeRect = createRect();
        //     // }
        //     console.log(rect);
        // });
        // 渲染
        rects.forEach(rect => {
            if (isBoom(rect, activeRect) && activeRect !== rect) {
                console.log('碰撞了', activeRect, rect);
                // activeRect.vx = 0;
                // activeRect.vy = 0;
                activeRect.y = rect.y - rect.h / 2 - activeRect.h / 2;
                activeRect = createRect();
            }
            rect.render(ctx)
        });
        // activeRect.render(ctx);

        // rects.forEach((rect, index) => {
        //     rect.y += rect.vy;
        //     rect.x += rect.vx;
        //     if (checkBound(rect)) {
        //         console.log('边界检测');
        //     }
        //     let rectsCopy = rects.slice(index + 1, rects.length);
        //     rectsCopy.forEach(rect2 => {
        //         if (isBoom(rect, rect2){
        //             console.log('碰撞检测');
        //         }
        //     });
        // });
        // ball.render(ctx);
    })()

</script>

</html>